/**
 * 
 */
package org.vision.contactsmanager.dao;

import java.text.Collator;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

import org.vision.contactsmanager.bean.MyContacts;

import android.content.ContentProviderOperation;
import android.content.ContentProviderResult;
import android.content.ContentUris;
import android.content.Context;
import android.content.Intent;
import android.content.OperationApplicationException;
import android.database.Cursor;
import android.net.Uri;
import android.os.RemoteException;
import android.provider.ContactsContract;
import android.provider.ContactsContract.RawContacts;
import android.provider.ContactsContract.CommonDataKinds.Email;
import android.provider.ContactsContract.CommonDataKinds.Note;
import android.provider.ContactsContract.CommonDataKinds.Phone;
import android.provider.ContactsContract.CommonDataKinds.StructuredName;
import android.provider.ContactsContract.CommonDataKinds.StructuredPostal;
import android.provider.ContactsContract.Contacts.Data;
import android.util.Log;

/**
 * @author dengjie
 *
 */
public class LocalContactsUtils {

    private Context context;
    public List<MyContacts> contactList = new ArrayList<MyContacts>();
    public PingyinComparator pingyinComparator;

    public LocalContactsUtils(Context context) {
        this.context = context;
        this.pingyinComparator = new PingyinComparator();
    }

    /**
     * 获取通过工具方法后，获取到的通讯录信息集合
     * @param contactList
     */
    public List<MyContacts> getContactList() {
        //按中文拼音顺序排序
        Collections.sort(contactList, pingyinComparator);
        return contactList;
    }

    //更新联系人,处于同一个事务中    
    public void updateToLContact(MyContacts myContacts) {
        ArrayList<ContentProviderOperation> ops = new ArrayList<ContentProviderOperation>();

        ops.add(ContentProviderOperation.newUpdate(ContactsContract.Data.CONTENT_URI).withSelection(
                Data.RAW_CONTACT_ID + "=?" + " AND " + ContactsContract.Data.MIMETYPE + " = ?",
                new String[] {myContacts.getContactsContractId(), StructuredName.CONTENT_ITEM_TYPE}).withValue(
                StructuredName.DISPLAY_NAME, myContacts.getName()).build());
        ops.add(ContentProviderOperation.newUpdate(ContactsContract.Data.CONTENT_URI).withSelection(
                Data.RAW_CONTACT_ID + "=?" + " AND " + ContactsContract.Data.MIMETYPE + " = ?" + " AND " + Phone.TYPE
                        + "=?",
                new String[] {myContacts.getContactsContractId(), Phone.CONTENT_ITEM_TYPE,
                        String.valueOf(Phone.TYPE_HOME)}).withValue(Phone.NUMBER, myContacts.getTelPhone()).build());
        ops.add(ContentProviderOperation.newUpdate(ContactsContract.Data.CONTENT_URI).withSelection(
                Data.RAW_CONTACT_ID + "=?" + " AND " + ContactsContract.Data.MIMETYPE + " = ?" + " AND " + Email.TYPE
                        + "=?",
                new String[] {myContacts.getContactsContractId(), Email.CONTENT_ITEM_TYPE,
                        String.valueOf(Email.TYPE_WORK)}).withValue(Email.DATA, myContacts.getEmail()).build());
        ops.add(ContentProviderOperation.newUpdate(ContactsContract.Data.CONTENT_URI).withSelection(
                Data.RAW_CONTACT_ID + "=?" + " AND " + ContactsContract.Data.MIMETYPE + " = ?",
                new String[] {myContacts.getContactsContractId(), StructuredPostal.CONTENT_ITEM_TYPE}).withValue(
                StructuredPostal.DATA, myContacts.getAddress()).build());
        ops.add(ContentProviderOperation.newUpdate(ContactsContract.Data.CONTENT_URI).withSelection(
                Data.RAW_CONTACT_ID + "=?" + " AND " + ContactsContract.Data.MIMETYPE + " = ?",
                new String[] {myContacts.getContactsContractId(), Note.CONTENT_ITEM_TYPE}).withValue(Note.NOTE,
                myContacts.getDescription()).build());
        ContentProviderResult[] results = null;
        try {
            results = context.getContentResolver().applyBatch(ContactsContract.AUTHORITY, ops);
        } catch (RemoteException e1) {
            Log.e("updateToLContact", e1.toString());
        } catch (OperationApplicationException e1) {
            Log.e("updateToLContact", e1.toString());
        }
    }

    //删除,处于同一个事务中    
    public void deleteFromLContact(MyContacts myContacts) {
        //获取该用户名的名称
        Cursor cursor = context.getContentResolver().query(ContactsContract.Data.CONTENT_URI,
                new String[] {Data.RAW_CONTACT_ID}, ContactsContract.Contacts.DISPLAY_NAME + "=?",
                new String[] {myContacts.getName()}, null);
        //循环删除
        ArrayList<ContentProviderOperation> ops = new ArrayList<ContentProviderOperation>();
        if (cursor.moveToFirst()) {
            do {
                long id = cursor.getLong(cursor.getColumnIndex(Data.RAW_CONTACT_ID));
                ops.add(ContentProviderOperation.newDelete(ContentUris.withAppendedId(RawContacts.CONTENT_URI, id))
                        .build());
                try {
                    context.getContentResolver().applyBatch(ContactsContract.AUTHORITY, ops);
                } catch (Exception e1) {
                    Log.e("deleteFromLContact", e1.toString());
                }
            } while (cursor.moveToNext());
            cursor.close();
        }
    }

    /**
     * 批量添加,处于同一个事务中
     * @return 返回新增的通讯录人员的本机ID
     */
    public String insertToLContact(MyContacts myContacts) {
        //文档位置：reference\android\provider\ContactsContract.RawContacts.html    
        ArrayList<ContentProviderOperation> ops = new ArrayList<ContentProviderOperation>();
        int rawContactInsertIndex = ops.size();
        ops.add(ContentProviderOperation.newInsert(RawContacts.CONTENT_URI).withValue(RawContacts.ACCOUNT_TYPE, null)
                .withValue(RawContacts.ACCOUNT_NAME, null).build());
        //文档位置：reference\android\provider\ContactsContract.Data.html    
        //插入用户名
        ops.add(ContentProviderOperation.newInsert(android.provider.ContactsContract.Data.CONTENT_URI)
                .withValueBackReference(Data.RAW_CONTACT_ID, rawContactInsertIndex).withValue(Data.MIMETYPE,
                        StructuredName.CONTENT_ITEM_TYPE).withValue(StructuredName.DISPLAY_NAME, myContacts.getName())
                .build());
        //插入电话号码
        ops.add(ContentProviderOperation.newInsert(android.provider.ContactsContract.Data.CONTENT_URI)
                .withValueBackReference(Data.RAW_CONTACT_ID, rawContactInsertIndex).withValue(Data.MIMETYPE,
                        Phone.CONTENT_ITEM_TYPE).withValue(Phone.NUMBER, myContacts.getTelPhone()).withValue(
                        Phone.TYPE, Phone.TYPE_MOBILE).withValue(Phone.LABEL, "手机号").build());
        //插入邮箱
        ops.add(ContentProviderOperation.newInsert(android.provider.ContactsContract.Data.CONTENT_URI)
                .withValueBackReference(Data.RAW_CONTACT_ID, rawContactInsertIndex).withValue(Data.MIMETYPE,
                        Email.CONTENT_ITEM_TYPE).withValue(Email.DATA, myContacts.getEmail()).withValue(Email.TYPE,
                        Email.TYPE_WORK).build());
        //插入地址
        ops.add(ContentProviderOperation.newInsert(android.provider.ContactsContract.Data.CONTENT_URI)
                .withValueBackReference(Data.RAW_CONTACT_ID, rawContactInsertIndex).withValue(Data.MIMETYPE,
                        StructuredPostal.CONTENT_ITEM_TYPE).withValue(StructuredPostal.DATA, myContacts.getAddress())
                .withValue(StructuredPostal.TYPE, StructuredPostal.TYPE_WORK).build());
        //插入备注
        ops.add(ContentProviderOperation.newInsert(android.provider.ContactsContract.Data.CONTENT_URI)
                .withValueBackReference(Data.RAW_CONTACT_ID, rawContactInsertIndex).withValue(Data.MIMETYPE,
                        Note.CONTENT_ITEM_TYPE).withValue(Note.NOTE, myContacts.getDescription()).build());
        String resultId = null;
        try {
            ContentProviderResult[] results = context.getContentResolver().applyBatch(ContactsContract.AUTHORITY, ops);
            Uri uri = results[0].uri;
            String path = uri.getPath();
            resultId = path.substring(path.lastIndexOf("/") + 1, path.length());
            Log.i("insertToLContact successed ", String.valueOf(results.length));
        } catch (RemoteException e1) {
            Log.e("insertToLContact", e1.toString());
        } catch (OperationApplicationException e1) {
            Log.e("insertToLContact", e1.toString());
        }
        return resultId;
    }

    //从本机中取号
    public void getLocalContact() {
        //读取手机中手机号
        Cursor cursor = context.getContentResolver().query(ContactsContract.Contacts.CONTENT_URI, null, null, null,
                null);
        
        String contactId = null;
        Cursor phone = null;
        while (cursor.moveToNext()) {
            //取得联系人名字
            int nameFieldColumnIndex = cursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME);

            // 取得联系人ID  
            contactId = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts._ID));
            phone = context.getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null,
                    ContactsContract.CommonDataKinds.Phone.CONTACT_ID + " = " + contactId, null, null);
            //取得电话号码
            // 取得电话号码(可能存在多个号码)  
            while (phone.moveToNext()) {
                String strPhoneNumber = phone.getString(phone
                        .getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
                MyContacts mc = new MyContacts();
                mc.setContactsContractId(contactId);
                mc.setName(cursor.getString(nameFieldColumnIndex));
                mc.setTelPhone(strPhoneNumber);
                if (isUserNumber(mc.getTelPhone())) {
                    if (!isContain(contactList, mc.getTelPhone())) {
                        contactList.add(mc);
                    }
                }
            }

        }
        cursor.close();
    }

    //从SIM卡中取号
    public void getSimContact(String add) {
        //读取SIM卡手机号,有两种可能:content://icc/adn与content://sim/adn
        try {
            Intent intent = new Intent();
            intent.setData(Uri.parse(add));
            Uri uri = intent.getData();
            Cursor cursor = context.getContentResolver().query(uri, null, null, null, null);
            if (cursor != null) {
                String contactId = null;
                while (cursor.moveToNext()) {
                    // 取得联系人ID  
                    contactId = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts._ID));

                    MyContacts mc = new MyContacts();
                    mc.setContactsContractId(contactId);
                    // 取得联系人名字
                    int nameFieldColumnIndex = cursor.getColumnIndex("name");
                    mc.setName(cursor.getString(nameFieldColumnIndex));
                    // 取得电话号码
                    int numberFieldColumnIndex = cursor.getColumnIndex("number");
                    mc.setTelPhone(cursor.getString(numberFieldColumnIndex));

                    if (isUserNumber(mc.getTelPhone())) {
                        if (!isContain(contactList, mc.getTelPhone())) {
                            contactList.add(mc);
                        }
                    }
                }
                cursor.close();
            }
        } catch (Exception e) {
            Log.i("eoe", e.toString());
        }
    }

    //是否为手机号码
    public static boolean isUserNumber(String num) {
        boolean re = false;
        if (num.length() == 11) {
            if (num.startsWith("13")) {
                re = true;
            } else if (num.startsWith("15")) {
                re = true;
            } else if (num.startsWith("18")) {
                re = true;
            }
        }
        return re;
    }

    //还原11位手机号
    public static String getNumber(String num) {
        if (num != null) {
            if (num.startsWith("+86")) {
                num = num.substring(3);
            } else if (num.startsWith("86")) {
                num = num.substring(2);
            }
        } else {
            num = "";
        }
        return num;
    }

    //是否在LIST有值
    public boolean isContain(List<MyContacts> list, String un) {
        for (int i = 0; i < list.size(); i++) {
            if (un.equals(list.get(i).getTelPhone())) {
                return true;
            }
        }
        return false;
    }

    //手输手机号的是否在通讯录中
    public boolean isAlreadyCheck(String[] Str, String un) {
        for (int i = 0; i < Str.length; i++) {
            if (un.equals(Str[i])) {
                return true;
            }
        }
        return false;
    }

    //通讯社按中文拼音排序
    public class PingyinComparator implements Comparator {
        public int compare(Object o1, Object o2) {
            MyContacts c1 = (MyContacts) o1;
            MyContacts c2 = (MyContacts) o2;
            Comparator cmp = Collator.getInstance(java.util.Locale.CHINA);
            return cmp.compare(c1.getName(), c2.getName());
        }

    }
}
